package hn.cch.service.impl;

import hn.cch.configuration.ApplicationConfiguration;
import hn.cch.constant.SystemConstant;
import hn.cch.service.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Service
public class FileServiceImpl implements FileService {


    private static final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);

    @Autowired
    private ApplicationConfiguration applicationConfiguration;

    public void getZipFile() {
        try {
            String path = applicationConfiguration.getDirectory();
            File zip = new File(path, "zip.zip");
            File oldFile = new File(path, "old");
            // 解压
            upZipFile(zip, oldFile);
            System.out.println(zip.delete());
            File[] listFiles = oldFile.listFiles();
            FileOutputStream fileOutputStream = new FileOutputStream(zip);
            CheckedOutputStream checkedOutputStream = new CheckedOutputStream(fileOutputStream, new Adler32());
            ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream);
            assert listFiles != null;
            List<File> fileList = new ArrayList<>(Arrays.asList(listFiles));
            byte[] buffer = new byte[SystemConstant.BUFFER_LENGTH];
            int size;
            for (File file : fileList) {
                System.out.println(file.getName());
                String name = "copy-" + file.getName();
                zipOutputStream.putNextEntry(new ZipEntry(name));
                InputStream inputStream = Files.newInputStream(file.toPath());
                while ((size = inputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, size);
                }
                inputStream.close();
                zipOutputStream.closeEntry();
                file.delete();
            }
            zipOutputStream.close();
            checkedOutputStream.close();
            fileOutputStream.close();
            oldFile.delete();

            File newFile = new File(path, "new");
            upZipFile(zip, newFile);
            Arrays.stream(Objects.requireNonNull(newFile.listFiles())).forEach(p -> System.out.println(p.getName()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void upZipFile(File zip, File folder) throws Exception {
        if (!folder.exists()) {
            logger.info("folder.mkdirs:{}", folder.mkdirs());
        }
        byte[] buffer = new byte[SystemConstant.BUFFER_LENGTH];
        int size;
        try (FileInputStream fileInputStream = new FileInputStream(zip);
             ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);) {
            ZipEntry zipEntry = null;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                File file = new File(folder, zipEntry.getName());
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    logger.info("parentFile.mkdirs:{}", parentFile.mkdirs());
                }
                if (file.exists()) {
                    logger.info("file.delete:{}", file.delete());
                }
                try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                    while ((size = zipInputStream.read(buffer)) > 0) {
                        fileOutputStream.write(buffer, 0, size);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
